package scenic;

import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Iterator;

import scenic.geom.Affine2;

/**
 * This class is a base class for scene nodes that contain other
 * scene nodes. The child nodes are painted starting from the first
 * child.
 */
public class SceneContainer extends SceneNode implements SceneParent {
	private ArrayList<SceneNode> children = new ArrayList<SceneNode>();

	/**
	 * Constructs an empty SceneContainer.
	 */
	public SceneContainer() {
	}
	
	/**
	 * Adds a child node to the given index in the child list.
	 * 
	 * @param index the index in the child list.
	 * @param node the child node.
	 */
	public void add(int index, SceneNode node) {
		if(node == null)
			throw new IllegalArgumentException();
		children.add(index, node);
		if(isVisible())
			node.addVisibleParent(this);
		changed(null);
	}

	/**
	 * Adds a child node at the end of the child list.
	 * 
	 * @param node the child node.
	 */
	public void add(SceneNode node) {
		if(node == null)
			throw new IllegalArgumentException();
		children.add(node);
		if(isVisible())
			node.addVisibleParent(this);
		changed(null);
	}

	/**
	 * Removes all child nodes from this container.
	 */
	public void clear() {
		Iterator<SceneNode> itr = children.iterator();
		
		if(isVisible()) {
			while(itr.hasNext()) {
					itr.next().removeVisibleParent(this);
			}
		}
		children.clear();
		changed(null);
	}

	public void remove(SceneNode node) {
		children.remove(node);
		if(isVisible())
			node.removeVisibleParent(this);
		changed(null);
	}
	
	void draw(DrawContext context, Affine2 transform, Rectangle visibleArea) {
		Iterator<SceneNode> itr = children.iterator();
		
		while(itr.hasNext())
			itr.next().draw(context, transform, visibleArea);		
	}
	
	void prepareDraw(DrawContext context, Affine2 transform) {
		Iterator<SceneNode> itr = children.iterator();
		
		while(itr.hasNext())
			itr.next().prepareDraw(context, transform);		
	}
	
	Rectangle getBounds(DrawContext context, Affine2 transform) {
		Rectangle result = new Rectangle();
		Iterator<SceneNode> itr = children.iterator();
		
		while(itr.hasNext()) {
			SceneNode node = itr.next();
			Rectangle nodeRect = node.getBounds(context, transform);
			
			Util.combine(result, nodeRect);
		}

		return result;
	}	
	
	int getDrawType(DrawContext context, Affine2 transform) {
		if(children.size() == 1)
			return ((SceneNode)children.get(0)).getDrawType(context, transform);
		return SceneNode.DRAW_SIMPLE;
	}
	
	protected void show() {
		Iterator<SceneNode> itr = children.iterator();
		
		while(itr.hasNext())
			itr.next().addVisibleParent(this);
	}
	
	protected void hide() {
		Iterator<SceneNode> itr = children.iterator();
		
		while(itr.hasNext())
			itr.next().removeVisibleParent(this);
	}
	
	public void childChanged(Rectangle area) {
			changed(area);
	}
}
